package com.bilibili.dubbo.api;

import com.bilibili.dubbo.api.mongo.RecommendUserApi;
import com.bilibili.model.mongo.RecommendUser;
import com.bilibili.model.mongo.UserLike;
import com.bilibili.model.vo.PageResult;
import io.jsonwebtoken.lang.Collections;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author HuangRongFu
 * 2021/11/19 星期五8:52 下午
 */

@DubboService
public class RecommendUserApiImpl implements RecommendUserApi {

    //这个地方最后的处理是去mongoDB数据库查找 所以用MongoTemplate
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 每日佳人
     *
     * @param: loginUserId
     * @Return: RecommendUser
     */
    @Override
    public RecommendUser queryWithMaxScore(Long loginUserId) {

        Query query = new Query();

        //设置条件通过用户的id去查询
        query.addCriteria(Criteria.where("toUserId").is(loginUserId));

        //第二个条件是取出查询出来的分数 倒序排序  取出最高值
        query.with(Sort.by(Sort.Order.desc("score")));

        //业务是查询一个 所有接收的时候就是一个对象就可以
        RecommendUser recommendUsers = mongoTemplate.findOne(query, RecommendUser.class);

        return recommendUsers;
    }

    /**
     * 每日推荐
     *
     * @param: userId
     * @param: page
     * @param: pageSize
     * @Return: PageResult
     */
    @Override
    public PageResult findPage(Long userId, Long page, Long pageSize) {

        //统计总数  构建查询条件 是通过登录用户id去查询
        Query query = new Query();
        //登录用户id  就是表中的toUserId
        query.addCriteria(Criteria.where("toUserId").is(userId));

        //查询总记录数 通过登录用户id 设置后可以查出登录用户有多少个推荐的用户id
        long total = mongoTemplate.count(query, RecommendUser.class);

        List<RecommendUser> recommendUserList = new ArrayList<>();
        // 如果推荐用户记录条数 >0
        if (total > 0) {

            //设置分页参数 skip(有多少页) limit(每页的记录数)
            query.skip((page - 1) * pageSize).limit(pageSize.intValue());

            recommendUserList = mongoTemplate.find(query, RecommendUser.class);
        }

        //封装到pageResult中返回
        return new PageResult(page, pageSize, total, recommendUserList);

    }

    /**
     * 佳人信息
     *
     * @param: userId
     * @param: toUSerId
     * @Return: RecommendUser
     */
    @Override
    public RecommendUser queryByUserId(Long userId, Long toUSerId) {

        Query query = new Query(Criteria.where("toUserId").is(toUSerId).and("userId").is(userId));

        RecommendUser user = mongoTemplate.findOne(query, RecommendUser.class);

        if (user == null){

            user = new RecommendUser();
            user.setUserId(userId);
            user.setToUserId(toUSerId);

            user.setScore(Double.valueOf(65 + userId%10));
        }

        return user;
    }

    /**
     * 推荐用户列表
     *
     * @param: loginUserId
     * @param: i
     * @Return: List
     */
    @Override
    public List<RecommendUser> queryCardsList(Long loginUserId, int counts) {

        Query query = new Query(Criteria.where("userId").is(loginUserId));

        //喜欢用户列表
        List<UserLike> userLikeList = mongoTemplate.find(query, UserLike.class);

        //喜欢用户的id集合
        List<Long> likeUserIds = userLikeList.stream().map(UserLike::getUserId).collect(Collectors.toList());

        //构建随机取样的条件
        Criteria criteria = Criteria.where("toUserId").is(loginUserId).and("userId").nin(likeUserIds);

        //3、使用统计函数，随机获取推荐的用户列表
        TypedAggregation<RecommendUser> newAggregation = TypedAggregation.newAggregation(RecommendUser.class,
                Aggregation.match(criteria),//指定查询条件
                Aggregation.sample(counts)//取样的数量
        );
        AggregationResults<RecommendUser> results = mongoTemplate.aggregate(newAggregation, RecommendUser.class);

        //4、构造返回
        return results.getMappedResults();
    }


}
